import numpy as np


def mse_f(x):
    return x ** 3 * (14315 / 72 - 5775 * np.log(3) / 32) - 9 * np.log(3) + x ** 2 * (
            63 * np.log(3) / 2 - 1021 / 30) + x * (3285 * np.log(3) / 32 - 2707 / 24) + 99 / 10


def che_f(x):
    return (1665 - 960 * np.sqrt(3) + (-15632 + 9024 * np.sqrt(3)) * x + (
            22016 - 12672 * np.sqrt(3)) * x ** 3 + 30 * np.log(7 / 4 + np.sqrt(3)) - 15 * np.log(
        97 / 16 + 7 * np.sqrt(3) / 2) + x ** 2 * (
                    -3750 + 2160 * np.sqrt(3) + 30 * np.log(97 / 16 + 7 * np.sqrt(3) / 2))) / 120


def _lagrange_interp_helper(x, nodes, j: int, n: int):
    assert (0 <= j <= n)
    prod = 1.0
    for i in range(n + 1):
        if i == j:
            continue
        prod *= (x - nodes[i]) / (nodes[j] - nodes[i])
    return prod


def lag_f(x):
    s = 0.0
    nodes = [np.cos((2 * i + 1) * np.pi / 8) for i in range(4)]
    for i in range(4):
        s = s + _lagrange_interp_helper(x, nodes, i, 3) * func(nodes[i])
    return s


def func(x):
    return x ** 2 * np.log(2 + x)
